package com.colorfruit.admin.business.service.impl;

import com.colorfruit.admin.business.dao.*;
import com.colorfruit.admin.pojo.entity.*;
import com.colorfruit.admin.pojo.enums.*;
import com.colorfruit.admin.pojo.vo.order.LogicInfoVo;
import com.colorfruit.admin.pojo.vo.payorder.PayOrderItemVo;
import com.colorfruit.framework.model.pojo.BaseResult;

import com.colorfruit.admin.business.service.OrderService;
import com.colorfruit.admin.pojo.vo.order.OrderTotalVo;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Slf4j
@Service
@Transactional
public class OrderServiceImpl implements OrderService {

    @Autowired
    PayBusinessOrderMapper payBusinessOrderMapper;

    @Autowired
    PayBusinessOrderItemMapper payBusinessOrderItemMapper;

    @Autowired
    PayUserWalletFlowMapper payUserWalletFlowMapper;

    @Autowired
    GlobalProcessionControlMapper globalProcessionControlMapper;

    @Autowired
    DriverInfoMapper driverInfoMapper;

    @Autowired
    PayWxOrderMapper payWxOrderMapper;

    @Autowired
    FoundationUserReceiveAddressMapper userReceiveAddressMapper;

    @Autowired
    FoundationPickGoodsAddressMapper pickGoodsAddressMapper;

    @Autowired
    FoundationSysUserMapper foundationSysUserMapper;

    @Autowired
    LogicTransportInfoMapper logicTransportInfoMapper;

    @Autowired
    PurchasePriceCountMapper purchasePriceCountMapper;

    @Override
    public PageInfo selectNotPayOrderList(String userId, int page , int size) {
        log.info("[service] [IN] selectNotPayOrderList param : userId = {}, page = {}, size = {}", userId, page, size);
        GlobalProcessionControl recentProcession = globalProcessionControlMapper.getRecentProcession();
        PageHelper.startPage(page, size);
        List<PayBusinessOrder> payBusinessOrders = payBusinessOrderMapper.selectPayBusinessOrderListGlobal(userId, PayBusinessOrderEnum.CONFIRMED.getCode(), recentProcession.getId());
        PageInfo<PayBusinessOrder> payBusinessOrderPageInfo = new PageInfo<>(payBusinessOrders);
        List<OrderTotalVo> orderTotalList = new ArrayList<>();
        for (PayBusinessOrder payBusinessOrder : payBusinessOrders) {
            OrderTotalVo orderTotalVo = new OrderTotalVo();
            orderTotalVo.setProductNum(payBusinessOrder.getTotalProductNum());
            orderTotalVo.setTotalAmount(payBusinessOrder.getTotalFee());
            orderTotalVo.setBusinessNo(payBusinessOrder.getBusinessOrderNo());
            List<PayOrderItemVo> payOrderItemVos = payBusinessOrderItemMapper.selectOrderItemList(payBusinessOrder.getBusinessOrderNo());
            orderTotalVo.setPayOrderItemVoList(payOrderItemVos);
            orderTotalList.add(orderTotalVo);
        }
        PageInfo<OrderTotalVo> orderTotalVoPageInfo = new PageInfo<>(orderTotalList);
        orderTotalVoPageInfo.setSize(payBusinessOrderPageInfo.getSize());
        log.info("[service] [OUT] selectNotPayOrderList success ");
        return orderTotalVoPageInfo;
    }

    @Override
    public PageInfo selectNotTransportOrderList(String userId, int page, int size) {
        log.info("[service] [IN] selectNotTransportOrderList param : userId = {}, page = {}, size = {}", userId, page, size);
        PageHelper.startPage(page, size);
        List<PayBusinessOrder> payBusinessOrders = payBusinessOrderMapper.selectPayBusinessOrderList(userId, PayBusinessOrderEnum.PAYED.getCode());
        PageInfo<PayBusinessOrder> payBusinessOrderPageInfo = new PageInfo<>(payBusinessOrders);
        List<OrderTotalVo> orderTotalList = new ArrayList<>();
        for (PayBusinessOrder payBusinessOrder : payBusinessOrders) {
            OrderTotalVo orderTotalVo = new OrderTotalVo();
            orderTotalVo.setProductNum(payBusinessOrder.getTotalProductNum());
            orderTotalVo.setTotalAmount(payBusinessOrder.getTotalFee());
            orderTotalVo.setBusinessNo(payBusinessOrder.getBusinessOrderNo());
            List<PayOrderItemVo> payOrderItemVos = payBusinessOrderItemMapper.selectOrderItemList(payBusinessOrder.getBusinessOrderNo());
            orderTotalVo.setPayOrderItemVoList(payOrderItemVos);
            orderTotalList.add(orderTotalVo);
        }
        PageInfo<OrderTotalVo> orderTotalVoPageInfo = new PageInfo<>(orderTotalList);
        orderTotalVoPageInfo.setSize(payBusinessOrderPageInfo.getSize());
        log.info("[service] [OUT] selectNotTransportOrderList success ");
        return orderTotalVoPageInfo;
    }

    @Override
    public PageInfo selectNotSignOrderList(String userId, int page, int size) {
        log.info("[service] [IN] selectNotSignOrderList param : userId = {}, page = {}, size = {}", userId, page, size);
        GlobalProcessionControl recentProcession = globalProcessionControlMapper.getRecentProcession();
        PageHelper.startPage(page, size);
        List<PayBusinessOrder> payBusinessOrders = payBusinessOrderMapper.selectPayBusinessOrderList(userId, PayBusinessOrderEnum.TRANSPORT.getCode());
        PageInfo<PayBusinessOrder> payBusinessOrderPageInfo = new PageInfo<>(payBusinessOrders);
        List<OrderTotalVo> orderTotalList = new ArrayList<>();
        for (PayBusinessOrder payBusinessOrder : payBusinessOrders) {
            OrderTotalVo orderTotalVo = new OrderTotalVo();
            orderTotalVo.setProductNum(payBusinessOrder.getTotalProductNum());
            orderTotalVo.setTotalAmount(payBusinessOrder.getTotalFee());
            orderTotalVo.setBusinessNo(payBusinessOrder.getBusinessOrderNo());
            List<PayOrderItemVo> payOrderItemVos = payBusinessOrderItemMapper.selectOrderItemList(payBusinessOrder.getBusinessOrderNo());
            orderTotalVo.setPayOrderItemVoList(payOrderItemVos);
            orderTotalList.add(orderTotalVo);
        }
        PageInfo<OrderTotalVo> orderTotalVoPageInfo = new PageInfo<>(orderTotalList);
        orderTotalVoPageInfo.setSize(payBusinessOrderPageInfo.getSize());
        log.info("[service] [OUT] selectNotSignOrderList success ");
        return orderTotalVoPageInfo;
    }

    @Override
    public PageInfo selectSignedOrderList(String userId, int page, int size) {
        log.info("[service] [IN] selectSignedOrderList param : userId = {}, page = {}, size = {}", userId, page, size);
        PageHelper.startPage(page, size);
        List<PayBusinessOrder> payBusinessOrders = payBusinessOrderMapper.selectPayBusinessOrderList(userId, PayBusinessOrderEnum.SIGNED.getCode());
        PageInfo<PayBusinessOrder> payBusinessOrderPageInfo = new PageInfo<>(payBusinessOrders);
        List<OrderTotalVo> orderTotalList = new ArrayList<>();
        for (PayBusinessOrder payBusinessOrder : payBusinessOrders) {
            OrderTotalVo orderTotalVo = new OrderTotalVo();
            orderTotalVo.setProductNum(payBusinessOrder.getTotalProductNum());
            orderTotalVo.setTotalAmount(payBusinessOrder.getTotalFee());
            orderTotalVo.setBusinessNo(payBusinessOrder.getBusinessOrderNo());
            List<PayOrderItemVo> payOrderItemVos = payBusinessOrderItemMapper.selectOrderItemList(payBusinessOrder.getBusinessOrderNo());
            orderTotalVo.setPayOrderItemVoList(payOrderItemVos);
            orderTotalList.add(orderTotalVo);
        }
        PageInfo<OrderTotalVo> orderTotalVoPageInfo = new PageInfo<>(orderTotalList);
        orderTotalVoPageInfo.setSize(payBusinessOrderPageInfo.getSize());
        log.info("[service] [OUT] selectSignedOrderList success ");
        return orderTotalVoPageInfo;

    }

    @Override
    public BaseResult cancelOrder(String businessNo, String userId) {
        log.info("[service] [IN] cancelOrder param : businessNo = {}", businessNo);
        PayBusinessOrder payBusinessOrder = payBusinessOrderMapper.getByBusinessNo(businessNo);
        if (payBusinessOrder == null){
            return new BaseResult(ErrorCodeEnum.DATA_ERROR.getCode(), "没有这个订单");
        }
        if (payBusinessOrder.getRecordStatus() == PayBusinessOrderEnum.CANCEL.getCode()){
            return new BaseResult(ErrorCodeEnum.DATA_ERROR.getCode(), "订单已被取消, 无需重复取消");
        }
        GlobalProcessionControl globalProcessionControl = globalProcessionControlMapper.getRecentProcession();
        if (globalProcessionControl.getRecordStatus() > (byte)2){
            return new BaseResult(ErrorCodeEnum.DATA_ERROR.getCode(), "采购阶段, 下单不允许撤回");
        }
        payBusinessOrderMapper.cancelOrder(businessNo);
        if (payBusinessOrder.getRecordStatus() == PayBusinessOrderEnum.PAYED.getCode()){
            PayUserWalletFlow payUserWalletFlow = new PayUserWalletFlow();
            payUserWalletFlow.setUserId(userId);
            payUserWalletFlow.setRecordStatus(StatusEnum.EFFECTIVE_STATUS.getStatusCode());
            payUserWalletFlow.setWalletType((byte)1);
            payUserWalletFlow.setBalance(payBusinessOrder.getTotalFee());
            payUserWalletFlow.setBusinessOrderNo(payBusinessOrder.getBusinessOrderNo());
            payUserWalletFlow.setPayOrderNo(null);
            payUserWalletFlow.setOuterOrderNo(null);
            payUserWalletFlow.setCreateTime(new Date());
            payUserWalletFlow.setUpdateTime(new Date());
            payUserWalletFlowMapper.insert(payUserWalletFlow);

            foundationSysUserMapper.updateWalletAmount(userId, payBusinessOrder.getTotalFee());
        }
        log.info("[service] [OUT] cancelOrder success ");
        return new BaseResult(ErrorCodeEnum.SUCCESS);
    }

    @Override
    public BaseResult confirmReceiveProduct(String userId, String businessNo) {
        log.info("[service] [IN] confirmReceiveProduct param : businessNo = {}", businessNo);
        //1. 签收订单
        PayBusinessOrder payBusinessOrder = payBusinessOrderMapper.getByBusinessNo(businessNo);
        GlobalProcessionControl globalProcessionControl = globalProcessionControlMapper.selectByPrimaryKey(payBusinessOrder.getGlobalControlId());
        if (globalProcessionControl.getRecordStatus() < GlobalStatusEnum.TRANSPORT.getCode()){
            return new BaseResult(ErrorCodeEnum.DATA_ERROR.getCode(), "运输阶段才能签收");
        }
        if (payBusinessOrder == null){
            return new BaseResult(ErrorCodeEnum.DATA_ERROR.getCode(), "没有这个订单");
        }
        if (payBusinessOrder.getRecordStatus() == PayBusinessOrderEnum.SIGNED.getCode()){
            return new BaseResult(ErrorCodeEnum.DATA_ERROR.getCode(), "订单已被签收, 无需重复签收");
        }
        payBusinessOrderMapper.signOrder(businessNo);
        // 2. 退钱
        BigDecimal totalAmount = new BigDecimal(0);
        List<PayOrderItemVo> payOrderItemVos = payBusinessOrderItemMapper.selectOrderItemList(businessNo);
        for (PayOrderItemVo payOrderItemVo : payOrderItemVos) {
            BigDecimal itemSaleMaxPrice = payOrderItemVo.getItemSaleMaxPrice();
            PurchasePriceCount purchasePriceCount = purchasePriceCountMapper.getPurchasePriceById(payBusinessOrder.getGlobalControlId(), payOrderItemVo.getProductId());
            BigDecimal purchasePricePickAddress = purchasePriceCount.getPurchasePricePickAddress();

            BigDecimal returnPrice = itemSaleMaxPrice.subtract(purchasePricePickAddress);
            BigDecimal returnAmount = returnPrice.multiply(new BigDecimal(payOrderItemVo.getItemProductNum()));
            totalAmount = totalAmount.add(returnAmount);

            PayUserWalletFlow payUserWalletFlow = new PayUserWalletFlow();
            payUserWalletFlow.setUserId(userId);
            payUserWalletFlow.setRecordStatus(StatusEnum.EFFECTIVE_STATUS.getStatusCode());
            if (returnAmount.compareTo(new BigDecimal(0)) > 0){
                payUserWalletFlow.setWalletType(FlowTypeEnum.IN.getCode());
            }else {
                payUserWalletFlow.setWalletType(FlowTypeEnum.OUT.getCode());
            }
            payUserWalletFlow.setBalance(returnAmount);
            payUserWalletFlow.setBusinessOrderNo(payBusinessOrder.getBusinessOrderNo());
            payUserWalletFlow.setPayOrderNo(null);
            payUserWalletFlow.setOuterOrderNo(null);
            payUserWalletFlow.setCreateTime(new Date());
            payUserWalletFlow.setUpdateTime(new Date());
            payUserWalletFlowMapper.insert(payUserWalletFlow);
        }
        FoundationSysUser foundationSysUser = foundationSysUserMapper.selectByPrimaryKey(userId);
        foundationSysUser.setWalletBalance(foundationSysUser.getWalletBalance().add(totalAmount));
        foundationSysUser.setLastUpdateTime(new Date());
        foundationSysUserMapper.updateByPrimaryKeySelective(foundationSysUser);
        log.info("[service] [OUT] confirmReceiveProduct success ");
        return new BaseResult(ErrorCodeEnum.SUCCESS);
    }

    @Override
    public BaseResult searchLogicInfo(String businessNo) {
        log.info("[service] [IN] searchLogicInfo param : businessNo = {}", businessNo);
        PayBusinessOrder payBusinessOrder = payBusinessOrderMapper.getByBusinessNo(businessNo);
        LogicInfoVo logicInfoVo = new LogicInfoVo();
        logicInfoVo.setAddressType(payBusinessOrder.getAddressType());
        Byte recordStatus = payBusinessOrder.getRecordStatus();
        //已支付
        if (recordStatus == PayBusinessOrderEnum.PAYED.getCode()){
            logicInfoVo.setLogicStage(LogicEnum.PURCHASING.getCode());
            PayWxOrder orderByBusinessNo = payWxOrderMapper.getOrderByBusinessNo(businessNo);
            logicInfoVo.setPurchaseTime(orderByBusinessNo.getCreateTime());
        }
        //已发货
        if (recordStatus == PayBusinessOrderEnum.TRANSPORT.getCode()){
            logicInfoVo.setLogicStage(LogicEnum.TRANSPORT.getCode());
            Long globalControlId = payBusinessOrder.getGlobalControlId();
            Long distributeAddressId = payBusinessOrder.getDistributeAddressId();
            DriverInfo driverInfo = driverInfoMapper.getDriverInfo(globalControlId, distributeAddressId);
            logicInfoVo.setTransportTime(driverInfo.getCreateTime());
            logicInfoVo.setCarNum(driverInfo.getCarNum());
            logicInfoVo.setDriverName(driverInfo.getDriverName());

            LogicTransportInfo logicTransportInfo = logicTransportInfoMapper.getLogicTransportInfo(globalControlId, distributeAddressId);
            //到达目的地
            if (logicTransportInfo.getRecordStatus() == TransportEnum.ARRIVAL_PICK_ADDRESS.getCode()){
                logicInfoVo.setLogicStage(LogicEnum.ARRIVAL.getCode());
                FoundationPickGoodsAddress foundationPickGoodsAddress = pickGoodsAddressMapper.selectByPrimaryKey(logicTransportInfo.getPickAddressId());
                logicInfoVo.setArrivalPickAddressTime(logicTransportInfo.getArrivalTime());
                logicInfoVo.setPickerName(foundationPickGoodsAddress.getPickerName());
                logicInfoVo.setPickerPhone(foundationPickGoodsAddress.getPickerPhone());
                logicInfoVo.setPickerAddress(foundationPickGoodsAddress.getAddressDescription());
            }
        }
        //配送中
        if (recordStatus == PayBusinessOrderEnum.DISTRIBUTE.getCode()){
            logicInfoVo.setLogicPicture(payBusinessOrder.getLogicPicture());
            logicInfoVo.setDistributorTime(payBusinessOrder.getDistributeTime());
        }
        if (recordStatus == PayBusinessOrderEnum.SIGNED.getCode()) {
            logicInfoVo.setSignedTime(payBusinessOrder.getSignTime());
        }
            log.info("[service] [OUT] searchLogicInfo success ");
        return new BaseResult(logicInfoVo);
    }

    @Override
    public BaseResult searchTradeInfo(String businessNo) {
        return null;
    }


}
